package com.turtle3d.formallanguage.grammar;

import java.util.ArrayList;

import com.turtle3d.formallanguage.symbol.Symbol;
import com.turtle3d.util.Randomizer;

public class ProductionFamily
{
	private Symbol leftSideSymbol;

	private ArrayList<Production> productions = new ArrayList<Production>();

	public ProductionFamily(Symbol leftSideSymbol)
	{
		super();
		this.leftSideSymbol = leftSideSymbol;
	}

	public Symbol getLeftSideSymbol()
	{
		return leftSideSymbol;
	}

	public ArrayList<Production> getProductions()
	{
		return productions;
	}

	public boolean addProduction(Production production)
	{
		if (!production.getLeftSide().equals(leftSideSymbol)) return false;

		productions.add(production);
		return true;
	}

	public Production getProduction()
	{

		if (productions.size() == 1) 
			return productions.get(0);

		float weightSum = 0;
		for (Production production : productions)
			weightSum += production.getProbability();

		float level = 0;
		float rand = Randomizer.getRandomizer().getRandom().nextFloat();
		for (Production production : productions)
		{
			level += production.getProbability() / weightSum;
			if (rand <= level) 
				return production;
		}

		return null;

	}
	
	/**
	 * The first production with defined and met condition is chosen. 
	 * If there are conditions defined, but none is met, null is returned. 
	 * If there are none conditions defined, then a toss is made and
	 * one is chosen based on production weight.   
	 * 
	 * @param symbolSequence
	 * @param symbolIndex
	 * @return
	 */		
	public Production getProduction(ArrayList<Symbol> symbolSequence, int symbolIndex){
		
		boolean allConditionsNull = true;
		
		for(Production production: productions){
			if(production.getCondition()!=null){
				allConditionsNull = false;
				if(production.getCondition().check(symbolSequence, symbolIndex))
					return production;
			}
		}
		
		return allConditionsNull?getProduction():null;
	}

}
